import axios from 'axios'
import qs from 'qs'
import { ElLoading } from 'element-plus'
import { useUserStore } from '../store/user'
import { storeToRefs } from 'pinia'
import router from '../router'

// 创建带自定义配置的 axios 实例
const Service = axios.create({
    baseURL: 'api',
    timeout: 10 * 1000,
    withCredentials: true,
    headers: {
        'Content-Type': 'application/json',
        'X-Requested-With': 'XMLHttpRequest'
    }
})

// 请求拦截器
Service.interceptors.request.use(
    config => {
        const userStore = useUserStore()
        const { token } = storeToRefs(userStore)

        // 自动携带 Token
        if (token.value) {
            config.headers!.Authorization = token.value
            config.headers!.token = token.value
        }

        // 自动转换 GET/DELETE 的 data 参数为 query string
        if (['get', 'delete'].includes(config.method!.toLowerCase())) {
            if (config.data) {
                // 处理数组和嵌套对象参数
                const query = qs.stringify(config.data, {
                    arrayFormat: 'brackets',
                    encode: false
                })
                config.url = `${config.url}?${query}`
                config.data = undefined
            }
        }

        // 统一加载状态控制
        ElLoading.service({ fullscreen: true })
        return config
    },
    error => {
        ElLoading.service({ fullscreen: true }).close()
        return Promise.reject(error)
    }
)

// 响应拦截器
Service.interceptors.response.use(
    response => {
        ElLoading.service({ fullscreen: true }).close()

        // 统一处理响应数据结构
        return response.data.code === 200 ?
            response.data :
            Promise.reject(response.data)
    },
    error => {
        ElLoading.service({ fullscreen: true }).close()

        // 处理 403 未授权
        if (error.response?.status === 403) {
            router.replace('/login')
            return Promise.reject(new Error('登录状态已过期'))
        }

        // 统一错误处理
        const errMessage = error.response?.data?.message ||
            error.message ||
            '请求失败，请检查网络连接'
        return Promise.reject(new Error(errMessage))
    }
)

// 封装带自动参数转换的请求方法
export default {
    get: <T = any>(url: string, data?: any, config?: any): Promise<T> =>
        Service.get(url, { ...config, data }),

    delete: <T = any>(url: string, data?: any, config?: any): Promise<T> =>
        Service.delete(url, { ...config, data }),

    post: <T = any>(url: string, data?: any, config?: any): Promise<T> =>
        Service.post(url, data, config),

    put: <T = any>(url: string, data?: any, config?: any): Promise<T> =>
        Service.put(url, data, config)
}
